/**
 * ****************************************************************************
 * Project: RoboBridge
 * ----------------------------------------------------------------------------
 * -------------------------- [c]2012 - KrawallMann ---------------------------
 * ---------------------- http://www.krawallmann.de.tc/ -----------------------
 * ****************************************************************************
 * File: FixedPoi.java Package: tc.de.krawallmann.robobridge.visualization
 * Version: 1.0 Author(s): KrawallMann
 * ****************************************************************************
 * Description:
 * ****************************************************************************
 */
package tc.de.krawallmann.robobridge.visualization;

import java.awt.Color;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;

import eu.hansolo.steelseries.tools.Util;


/**
 * The Class FixedPoi.<br/>
 * Partially auto-generated Javadoc!
 */
public class FixedPoi {
	/** The location. */
	private final Point2D LOCATION;

	/** The name. */
	private final String NAME;

	/** The poi image. */
	private final BufferedImage POI_IMAGE = create_POI_Image(5);

	// <editor-fold defaultstate="collapsed" desc="Variable declaration">

	// </editor-fold>

	// <editor-fold defaultstate="collapsed" desc="Constructor">
	/**
	 * Defines a point of interest with the latitude and longitude of 0 which is
	 * somewhere in the atlanic ocean between south africa and america.
	 * 
	 * @param NAME
	 *            the name
	 */
	public FixedPoi(final String NAME) {
		this(NAME, 0, 0);
	}

	/**
	 * Defines a point of interest with the given name and the given coordinates
	 * as latitude and longitude in the format decimal degrees e.g. 51.485605,
	 * 7.479544
	 * 
	 * @param NAME
	 *            the name
	 * @param x
	 *            the x
	 * @param y
	 *            the y
	 */
	public FixedPoi(final String NAME, final double x, final double y) {
		// LAT = Y, LON = X
		this.NAME = NAME;
		LOCATION = new Point2D.Double(x, y);
	}

	/**
	 * Instantiates a new fixed poi.
	 * 
	 * @param NAME
	 *            the name
	 * @param angle
	 *            the angle
	 * @param radius
	 *            the radius
	 * @param angular
	 *            the angular
	 */
	public FixedPoi(final String NAME, final double angle, final double radius,
			final boolean angular) {
		this.NAME = NAME;
		if (angular) {
			final double x = Math.cos(Math.toRadians(angle + 90)) * Math.abs(radius);
			final double y = Math.sin(Math.toRadians(angle + 90)) * Math.abs(radius);
			LOCATION = new Point2D.Double(x, y);
		} else {
			LOCATION = new Point2D.Double(angle, radius);
		}
	}

	// </editor-fold>

	/**
	 * Returns the distance in meters of the poi to the coordinate defined by
	 * the given latitude and longitude. The calculation takes the earth radius
	 * into account.
	 * 
	 * @param x
	 *            the x
	 * @param y
	 *            the y
	 * @return the distance in meters to the given coordinate
	 */
	public double distanceTo(final double x, final double y) {
		final double dx = getLocation().getX() - x;
		final double dy = getLocation().getY() - y;
		return Math.sqrt(dx * dx + dy * dy);
	}

	// <editor-fold defaultstate="collapsed" desc="Misc">
	/**
	 * Returns the distance of the poi to the given poi in meters. The
	 * calculation takes the earth radius into account.
	 * 
	 * @param POINT_OF_INTEREST
	 *            the point of interest
	 * @return the distance in meters to the given poi
	 */
	public double distanceTo(final FixedPoi POINT_OF_INTEREST) {
		return distanceTo(POINT_OF_INTEREST.getLocationXY().getX(), POINT_OF_INTEREST
				.getLocationXY().getY());
	}

	/**
	 * Returns the location of the poi as Point2D.
	 * 
	 * @return the location of the poi
	 */
	public Point2D getLocation() {
		return LOCATION;
	}

	/**
	 * Returns the x,y coordinates of the poi.
	 * 
	 * @return x,y coordinates of the poi
	 */
	public Point2D getLocationXY() {
		return LOCATION;
	}

	// <editor-fold defaultstate="collapsed" desc="Getters and Setters">
	/**
	 * Returns the name of the point of interest.
	 * 
	 * @return the name of the point of interest
	 */
	public String getName() {
		return NAME;
	}

	/**
	 * Returns the image of the point of interest. This is for future use, e.g.
	 * for location specific images.
	 * 
	 * @return a buffered image that will be used to visualize the point of
	 *         interest
	 */
	public BufferedImage getPoiImage() {
		return POI_IMAGE;
	}

	/**
	 * Sets the location of the poi by the given latitude and longitude values.
	 * 
	 * @param x
	 *            the x
	 * @param y
	 *            the y
	 */
	public final void setLocation(final double x, final double y) {
		LOCATION.setLocation(x, y);
	}

	// </editor-fold>

	/**
	 * Sets the location of the poi by the given Point2D.
	 * 
	 * @param LOCATION
	 *            the new location
	 */
	public void setLocation(final Point2D LOCATION) {
		this.LOCATION.setLocation(LOCATION);
	}

	/*
	 * (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "FixedPoi [NAME=" + NAME + ", LOCATION=" + LOCATION + "]";
	}

	/**
	 * Creates the image of the poi.
	 * 
	 * @param WIDTH
	 *            the width
	 * @return buffered image of the poi
	 */
	private BufferedImage create_POI_Image(final int WIDTH) {
		if (WIDTH <= 0) {
			return null;
		}

		final java.awt.image.BufferedImage IMAGE =
				Util.INSTANCE.createImage(WIDTH, WIDTH, java.awt.Transparency.TRANSLUCENT);
		final java.awt.Graphics2D G2 = IMAGE.createGraphics();
		G2.setRenderingHint(java.awt.RenderingHints.KEY_ANTIALIASING,
				java.awt.RenderingHints.VALUE_ANTIALIAS_ON);
		// G2.setRenderingHint(java.awt.RenderingHints.KEY_RENDERING,
		// java.awt.RenderingHints.VALUE_RENDER_QUALITY);
		// G2.setRenderingHint(java.awt.RenderingHints.KEY_DITHERING,
		// java.awt.RenderingHints.VALUE_DITHER_ENABLE);
		// G2.setRenderingHint(java.awt.RenderingHints.KEY_ALPHA_INTERPOLATION,
		// java.awt.RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
		// G2.setRenderingHint(java.awt.RenderingHints.KEY_COLOR_RENDERING,
		// java.awt.RenderingHints.VALUE_COLOR_RENDER_QUALITY);
		G2.setRenderingHint(java.awt.RenderingHints.KEY_STROKE_CONTROL,
				java.awt.RenderingHints.VALUE_STROKE_PURE);
		// G2.setRenderingHint(java.awt.RenderingHints.KEY_TEXT_ANTIALIASING,
		// java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

		final java.awt.geom.Ellipse2D BLIP = new java.awt.geom.Ellipse2D.Double(0, 0, WIDTH, WIDTH);
		final java.awt.geom.Point2D CENTER =
				new java.awt.geom.Point2D.Double(BLIP.getCenterX(), BLIP.getCenterY());
		final float[] FRACTIONS = {
				0.0f, 1.0f
		};
		final Color[] COLORS = {
				new Color(1.0f, 1.0f, 1.0f, 0.9f), new Color(1.0f, 1.0f, 1.0f, 0.0f)
		};
		final java.awt.RadialGradientPaint GRADIENT =
				new java.awt.RadialGradientPaint(CENTER, (int) (WIDTH / 2.0), FRACTIONS, COLORS);
		G2.setPaint(GRADIENT);
		G2.fill(BLIP);

		G2.dispose();

		return IMAGE;
	}
}
